package com.sunyard.utils;

import lombok.extern.slf4j.Slf4j;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * @author zhix.huang
 * @version 1.0
 * @Title: DateUtil.java
 * @Package com.sydtech.bms.util
 * @Description: 日期工具类
 * @date 2017年11月10日 上午8:50:19
 */
@Slf4j
public class DateUtil {

    /**
     * @FIELD: TODO
     */
    public final static String DD = "dd";
    /**
     * @FIELD: TODO
     */
    public final static String MM = "MM";
    /**
     * @FIELD: TODO
     */
    public final static String HHMMSS = "HHmmss";
    /**
     * @FIELD: TODO
     */
    public final static String YYYY = "yyyy";
    /**
     * @FIELD: TODO
     */
    public final static String YYYYMM = "yyyyMM";
    /**
     * @FIELD: TODO
     */
    public final static String YYYY_MM = "yyy-MM";
    /**
     * @FIELD: TODO
     */
    public final static String MMDD = "MMdd";
    /**
     * @FIELD: TODO
     */
    public final static String YYYYMMDD = "yyyyMMdd";
    /**
     * @FIELD: TODO
     */
    public final static String YYYMMDD = "yyyMMdd";

    public final static String YYMMDD = "yyMMdd";
    /**
     * @FIELD: TODO
     */
    public final static String YYYY_MM_DD = "yyyy-MM-dd";
    /**
     * @FIELD: TODO
     */
    public final static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
    /**
     * @FIELD: TODO
     */
    public final static String YYYYMMDDHHMM = "yyyyMMddHHmm";
    /**
     * @FIELD: TODO
     */
    public final static String YYYYMMDD_HHMMSS = "yyyy-MM-dd HH:mm:ss";
    /**
     * @FIELD: TODO
     */
    public final static String HH_MM_SS_SSS = "HH:mm:ss.SSS";
    /**
     * @FIELD: TODO
     */
    public final static String HH_MM_SS = "HH:mm:ss";
    /**
     * @FIELD: TODO
     */
    public final static String YYYYMMDD_HHMMSSSSS = "yyyy-MM-dd-HH.mm.ss.SSSSSS";

    public final static String YYYYMMDD_HHMMSSSSS02 = "yyyy-MM-dd HH:mm:ss.SSS";
    /**
     * @FIELD: TODO
     */
    public final static String HHMMSSSSS = "HHmmssSSS";
    /**
     * @FIELD: TODO
     */
    public final static String MMDDHHmmss = "MMddHHmmss";

    /**
     * @param date
     * @return
     * @title getYear
     * @description 获取年份
     * @author Nan Ou
     * @email ou.nan@sunyard.com
     */
    public static String getYear(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(YYYY);
        return sdf.format(date);
    }

    /**
     * @param date
     * @return
     * @title getMonth
     * @description 获取月份
     * @author Nan Ou
     * @email ou.nan@sunyard.com
     */
    public static String getMonth(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(MMDD);
        return sdf.format(date);
    }

    public static boolean isOntime(long time, String start, String end) throws ParseException {
        SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
        Date nowTime = df.parse(df.format(new Date(time)));
        Date dayTimeStart = df.parse(start);
        Date dayTimeEnd = df.parse(end);
        return timeCalendar(nowTime, dayTimeStart, dayTimeEnd);
    }

    public static boolean timeCalendar(Date nowTime, Date dayTimeStart, Date dayTimeEnd) {
        //设置当前时间
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);
        //设置开始时间
        Calendar timeStart = Calendar.getInstance();
        timeStart.setTime(dayTimeStart);
        //设置结束时间
        Calendar timeEnd = Calendar.getInstance();
        timeEnd.setTime(dayTimeEnd);
        return date.after(timeStart) && date.before(timeEnd);
    }

    public static Long String2Long(String time) throws ParseException {
        if (time != null) {
            return new SimpleDateFormat("yyyyMMddHHmmss").parse(time).getTime();
        }
        return null;
    }

    /**
     * @param date
     * @return
     * @title getMonth
     * @description 获取月份
     * @author Nan Ou
     * @email ou.nan@sunyard.com
     */
    public static String getMon(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(MM);
        return sdf.format(date);
    }

    /**
     * @param date
     * @return
     * @title getDay
     * @description 获取日份
     * @author Nan Ou
     * @email ou.nan@sunyard.com
     */
    public static String getDay(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(DD);
        return sdf.format(date);
    }

    /**
     * 获取月份和日份
     */
    public static String getMMDD(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(MMDD);
        return sdf.format(date);
    }

    /**
     * 获取时间
     */
    public static String getTime(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(HHMMSS);
        return sdf.format(date);
    }

    /**
     * 将字符串解析成Date
     *
     * @param format
     * @param
     * @return
     * @throws ParseException
     */
    public static Date getDate(String format, String str) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        try {
            return dateFormat.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 将日期格式对象转化为指定格式的字符串
     * @param format
     * @param date
     * @return
     */

    public static String DateToStr(String format,Date date){
        return new SimpleDateFormat(format).format(date);
    }

    public static String getWeekOfDate(long dateLong) {
        Date date = new Date(dateLong);
        String[] weekDays = {"1", "2", "3", "4", "5", "6", "7"};
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 2;
        if (w < 0)
            w = 0;
        return weekDays[w];
    }

    /**
     * 获取yyyyMMddHHmmss格式日期
     *
     * @param str
     * @return Date
     */
    public static Date getDefaultDate(String str) {
        return getDate(YYYYMMDDHHMMSS, str);
    }

    /**
     * 将时间格式化成字符串
     *
     * @param format
     * @param date
     * @return
     */
    public static String getDateStr(String format, Date date) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        return dateFormat.format(date);
    }

    /**
     * 获取获取yyyyMMddHHmmss格式格式字符串
     *
     * @param date
     * @return
     */
    public static String getDefaultDateStr(Date date) {
        return getDateStr(YYYYMMDDHHMMSS, date);
    }

    /**
     * 获取当天开始时间
     *
     * @return Date
     */
    public static Date getStartOfTodDay() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 当天的结束时间
     *
     * @return
     */
    public static Date getEndOfTodDay() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    /**
     * 获取给定日期之前或之后若干天
     *
     * @param date 给定日期
     * @param day  偏移天数
     * @return
     */
    public static Date getOffDate(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, day);
        return calendar.getTime();
    }

    /**
     * 获取给定日期之前或之后若干月
     *
     * @param date
     * @param month
     * @return
     */
    public static Date getOffMonth(Date date, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, month);
        return calendar.getTime();
    }


    /**
     * 获取给定日期之前或之后若干分钟
     *
     * @param date
     * @param minute
     * @return
     */
    public static Date getOffMinute(Date date, int minute) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minute);
        return calendar.getTime();
    }

    /**
     * 获取给定日期之前或之后若秒
     *
     * @param date
     * @param
     * @return
     */
    public static Date getOffSecond(Date date, int second) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.SECOND, second);
        return calendar.getTime();
    }

    /**
     * Description: 根据开始时间和结束时间返回时间段内的时间集合
     *
     * @param beginDate
     * @param endDate
     * @return
     */
    public static List<Date> getDatesBetweenTwoDate(Date beginDate, Date endDate) {
        List<Date> lDate = new ArrayList<Date>();
        lDate.add(beginDate);// 把开始时间加入集合  
        Calendar cal = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间  
        cal.setTime(beginDate);
        boolean bContinue = true;
        while (bContinue) {
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量  
            cal.add(Calendar.DAY_OF_MONTH, 1);
            // 测试此日期是否在指定日期之后  
            if (endDate.after(cal.getTime())) {
                lDate.add(cal.getTime());
            } else {
                break;
            }
        }
        lDate.add(endDate);// 把结束时间加入集合  
        return lDate;
    }

    /**
     * @param date
     * @return
     */
    public static boolean isWorkDay(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        if (c.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY ||
                c.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * @param @param  smdate
     * @param @param  bdate
     * @param @return
     * @return int
     * @throws
     * @Title: daysBetween
     * @Description: 两个日期相差天数
     */
    public static int daysBetween(Date smdate, Date bdate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        smdate = sdf.parse(sdf.format(smdate));
        bdate = sdf.parse(sdf.format(bdate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();
        long between_days = (time2 - time1) / (1000 * 3600 * 24);

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * @param @param  smdate
     * @param @param  bdate
     * @param @return
     * @param @throws ParseException
     * @return int
     * @throws
     * @Title: monthsBetween
     * @Description: 两个月份相差月数
     */
    public static int monthsBetween(Date smdate, Date bdate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        smdate = sdf.parse(sdf.format(smdate));
        bdate = sdf.parse(sdf.format(bdate));
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
        cal1.setTime(smdate);
        cal2.setTime(bdate);
        int year = cal2.get(Calendar.YEAR) - cal1.get(Calendar.YEAR);

        return year * 12 + cal2.get(Calendar.MONTH) - cal1.get(Calendar.MONTH);
    }

    /**
     * @param dateStr
     * @return String
     * @throws
     * @Description: 将字符日期YYYYMMddHHmmss转化成字符日期yyyy-MM-dd HH:mm:ss
     * @author zhix.huang
     * @date 2017年11月10日 上午8:44:06
     */
    public static String dateformat(String dateStr) {
        if (dateStr == null) {
            return "";
        }
        SimpleDateFormat format1 = new SimpleDateFormat("yyyyMMddHHmmss");
        Date date1 = null;
        try {
            //先转化成date
            date1 = format1.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //date转化成string
        SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String str = format2.format(date1);
        return str;
    }

    /**
     * @Description:
     * @author zhix.huang
     * @date 2018/3/2 14:30
     */
    public static String mmdd(String st) {
        if (st == null) {
            return "";
        }

        SimpleDateFormat format1 = new SimpleDateFormat("MMdd");
        Date date1 = null;
        try {
            //先转化成date
            date1 = format1.parse(st);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //date转化成string
        SimpleDateFormat format2 = new SimpleDateFormat("MM月dd日");
        String str = format2.format(date1);
        return str;
    }

    /**
     * @param start_time
     * @param end_time
     * @param months
     * @return
     * @throws ParseException
     */
    public static boolean isBetweenMonths(String start_time, String end_time, int months) throws ParseException {

        Date startTime = DateUtil.getDefaultDate(start_time);
        Date endTime = DateUtil.getDefaultDate(end_time);
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(startTime);
        cal1.add(Calendar.MONTH, +months);
        Date time1 = cal1.getTime();
        long time2 = time1.getTime();
        long time4 = endTime.getTime();
        if (time2 >= time4) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * yyyy-MM-dd HH:mm:ss
     */


    public static String changeFormat(String start_time) throws ParseException {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMddHHmmss");
        Date format1 = sdf.parse(start_time);
        String s = sdf2.format(format1);
        return s;
    }

    /**
     * @param start_time     待转换的数据
     * @param fromFormatDate 待转换的日期格式，和start_time格式对应
     * @param toFormatDate   转换后的日期格式
     * @return 转换后的数据
     * @throws ParseException
     */
    public static String changeFormatDate(String start_time, String fromFormatDate, String toFormatDate) throws ParseException {

        SimpleDateFormat sdf = new SimpleDateFormat(fromFormatDate);
        SimpleDateFormat sdf2 = new SimpleDateFormat(toFormatDate);
        Date format1 = sdf.parse(start_time);
        String s = sdf2.format(format1);
        return s;
    }

    /**
     * @param args
     * @throws ParseException
     */
    public static void main(String[] args) throws ParseException {
        //boolean betweenMonths = isBetweenMonths("20180906023812", "20181206023813", 3);
//        String s = changeFormatDate("2018-08-09 11:23:12",YYYYMMDD_HHMMSS,YYYYMMDD);
//        System.out.println("s:"+s);
        /*String code = getCode(6);
        System.out.println(code);
        BigDecimal actualAmount = new BigDecimal(0);*/
        System.out.println(getDateFmt("2021-02-01", "start"));
        System.out.println(getDateFmt("2021-02-01", "end"));
        SimpleDateFormat format = new SimpleDateFormat(YYYYMMDD_HHMMSS);
        Date date = new Date(getQueryTime());
        System.out.println(format.format(date));
    }

    /**
     * @param len
     * @return
     */
    public static String getCode(int len) {
        StringBuilder sb = new StringBuilder();
        Random r = new Random();
        while (len > 0) {
            sb.append(r.nextInt(9));
            len--;
        }
        return sb.toString();
    }

    /**
     * yyyy-mm-dd转为yyyy-mm-dd HH:mm:ss
     *
     * @return
     */
    public static Date getDateFmt(String date, String type) {
        Date retDate = null;
        if ("start".equals(type)) {
            retDate = DateUtil.getDate("yyyy-MM-dd HH:mm:ss",
                    date + " 00:00:00");
        } else {
            retDate = DateUtil.getDate("yyyy-MM-dd HH:mm:ss",
                    date + " 23:59:59");
        }
        return retDate;
    }

    /**
     * 获取当天剩余的秒数
     *
     * @return
     */
    public static long getSeconds() {
        Calendar calendar = Calendar.getInstance();
        int seconds = 24 * 60 * 60 - (calendar.get(Calendar.HOUR_OF_DAY) * 3600 +
                calendar.get(Calendar.MINUTE) * 60 + calendar.get(Calendar.SECOND));
        return seconds;
    }

    /**
     * 判断日期是否为今天
     *
     * @param dateNum YYYYMMDD_HHMMSS
     */
    public static boolean isToday(String dateNum) {
        log.info("dateNum:{}", dateNum);
        try {
            String today = getDateStr(DateUtil.YYYY_MM_DD, new Date());
            log.info("今天的时间为:{}", today);
            String lastDate = changeFormatDate(dateNum, DateUtil.YYYYMMDD_HHMMSS, DateUtil.YYYY_MM_DD);
            if (today.equals(lastDate)) {
                return true;
            } else {
                return false;
            }
        } catch (ParseException e) {
            throw new RuntimeException("传入的参数格式错误");
        }
    }

    /**
     * 获取上月月份
     *
     * @return
     */
    public static String getLastMonth() {
        SimpleDateFormat format = new SimpleDateFormat("yyyyMM");
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date); // 设置为当前时间
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1); // 设置为上一个月
        date = calendar.getTime();
        return format.format(date);
    }

    public static long getQueryTime() {
        String startTimeQuery = "17:30:00";
        String endTimeQuery = "20:30:00";
        String queryTime = "";
        SimpleDateFormat sf = new SimpleDateFormat(HH_MM_SS);
        SimpleDateFormat sfTime = new SimpleDateFormat(YYYYMMDD_HHMMSS);
        SimpleDateFormat sfDay = new SimpleDateFormat(YYYY_MM_DD);
        Date date = new Date();
        String now = sf.format(date);
        long time = 0;
        try {
            Date nowTime = new SimpleDateFormat(HH_MM_SS).parse(now);
            Date startTime = new SimpleDateFormat(HH_MM_SS).parse(startTimeQuery);
            Date endTime = new SimpleDateFormat(HH_MM_SS).parse(endTimeQuery);
            Calendar date2 = Calendar.getInstance();
            date2.setTime(nowTime);
            Calendar begin = Calendar.getInstance();
            begin.setTime(endTime);
            if (isEffectiveDate(nowTime, startTime, endTime)) {
                queryTime = sfTime.format(date);
            } else if (date2.after(begin)) {
                queryTime = sfDay.format(date) + " " + endTimeQuery;
            } else {
                Date yesterday = yesterday(date);
                queryTime = sfDay.format(yesterday) + " " + endTimeQuery;
            }
            time = sfTime.parse(queryTime).getTime();
        } catch (java.text.ParseException e) {
            e.printStackTrace();
        }

        return time;
    }

    /**
     * 根据不同时间返回不同查询内容
     * @return Integer 1:查询实时数据--当前时间在17:30-20:30,2:查询昨天20.30数据--当前时间在17:30以前,3:查询今天20.30数据 -- 当前时间在20:30以后
     */
    public static Integer getQueryType(){
        String startTimeQuery = "17:30:00";
        String endTimeQuery = "20:30:00";
        Integer queryTime = null;
        SimpleDateFormat sf = new SimpleDateFormat(HH_MM_SS);
        Date date = new Date();
        String now = sf.format(date);
        try{
            Date nowTime = new SimpleDateFormat(HH_MM_SS).parse(now);
            Date startTime = new SimpleDateFormat(HH_MM_SS).parse(startTimeQuery);
            Date endTime = new SimpleDateFormat(HH_MM_SS).parse(endTimeQuery);
            SimpleDateFormat sfTime = new SimpleDateFormat(YYYYMMDD_HHMMSS);
            SimpleDateFormat sfDay = new SimpleDateFormat(YYYY_MM_DD);
            Calendar date2 = Calendar.getInstance();
            date2.setTime(nowTime);
            Calendar begin = Calendar.getInstance();
            begin.setTime(endTime);
            if (isEffectiveDate(nowTime, startTime, endTime)) {
                queryTime = 1;
            } else if (date2.after(begin)) {
                queryTime = 3;
            } else {
                queryTime = 2;
            }
        } catch (java.text.ParseException e) {
            log.error(e.getMessage());
        }
        return queryTime;

    }

    public static String getStringTime(){
        SimpleDateFormat format = new SimpleDateFormat(YYYYMMDD_HHMMSS);
        Date date = new Date(getQueryTime());
        return format.format(date);
    }

    /**
     * 获取昨天昨天日期
     */
    public static Date yesterday(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DATE, -1);
        return cal.getTime();
    }


    /**
     * 判断当前时间是否在[startTime, endTime]区间，注意时间格式要一致
     *
     * @param nowTime   当前时间
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return
     * @author tsz
     */
    public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
        if (nowTime.getTime() == startTime.getTime()
                || nowTime.getTime() == endTime.getTime()) {
            return false;
        }
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(startTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        if (date.after(begin) && date.before(end)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 时间日期转换
     * @param strDate 字符串yyyyMMddHHmmss
     * @return 字符串yyyy-MM-dd HH:mm:ss
     */
    public static String strToDateLong(String strDate) {
        Date date = new Date();
        try {
            date = new SimpleDateFormat("yyyyMMddHHmmss").parse(strDate);//先按照原格式转换为时间
        } catch (ParseException e) {
            e.printStackTrace();
        }
        String str = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);//再将时间转换为对应格式字符串
        return str;
    }
}
